package mrms.api.web.controllers;

import lombok.AllArgsConstructor;
import mrms.api.entity.MeetingEntity;
import mrms.api.entity.MeetingmemberEntity;
import mrms.api.entity.RoomEntity;
import mrms.api.entity.UserEntity;
import mrms.api.repository.MeetingMemberRepository;
import mrms.api.repository.MeetingRepository;
import mrms.api.repository.UserRepository;
import mrms.api.service.MeetingService;
import mrms.api.service.MessageService;
import mrms.api.service.UserService;
import mrms.api.web.dto.AdminUpdateMeetingDto;
import mrms.api.web.dto.MeetingDto;
import mrms.api.web.dto.RoomRequirementDto;
import mrms.api.web.dto.UserUpdateMeetingDto;
import mrms.api.web.utils.*;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lenchu
 * @date 2019/02/06
 */
@RestController
@AllArgsConstructor
public class MeetingController {
    private final MeetingRepository meetingRepository;
    private final MeetingMemberRepository meetingMemberRepository;
    private final UserRepository userRepository;
    private final UserService userService;
    private final MeetingService meetingService;
    private final MessageService messageService;

    @PostMapping("/meeting/autoroom")
    public Result autoRoom(@RequestBody RoomRequirementDto roomRequirementDto,
                           @RequestAttribute("user") UserEntity user) {
        MeetingEntity meetingEntity = new MeetingEntity();
        RoomEntity roomEntity = new RoomEntity();
        BeanUtils.copyProperties(roomRequirementDto, meetingEntity);
        BeanUtils.copyProperties(roomRequirementDto, roomEntity);

        roomEntity.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        roomEntity.setType(RoomType.VIRTUAL);
        roomEntity.setPermission(user.getPermission());

        meetingEntity.setAdjust(MeetingAdjust.ADJUSTING);
        meetingEntity.setSponsor(user.getId());
        return Result.success(meetingService.saveMeetingAndAutoRoom(meetingEntity, roomEntity));
    }

    @PostMapping("/meeting")
    public Result save(@RequestBody MeetingDto meetingDto, @RequestAttribute("user")UserEntity user) {
        if ((meetingDto.getEndtime().doubleValue()-meetingDto.getStarttime().doubleValue())/(60*60*24)>2){
            return Result.error("会议时间过长");
        }
        long startTime=meetingDto.getStarttime()-15*60;
        long endTime=meetingDto.getEndtime()+15*60;
        List<MeetingEntity> meetingEntities=meetingRepository.findByStarttimeBetweenAndEndtimeBetweenAndRoom(startTime,endTime,startTime,endTime,meetingDto.getRoom());
        List<MeetingEntity> meetingEntities1=meetingRepository.findByStarttimeLessThanEqualAndEndtimeGreaterThanEqualAndRoom(startTime,endTime,meetingDto.getRoom());
        if (meetingEntities.size()>0||meetingEntities1.size()>0){
            return Result.error("该时间段会议室已被预订");
        }

        MeetingEntity meetingEntity = new MeetingEntity();
        BeanUtils.copyProperties(meetingDto, meetingEntity);
        meetingEntity.setSponsor(user.getId());
        meetingEntity.setState(MeetingState.CHECK_PENDING);
        meetingEntity.setAdjust(MeetingAdjust.NEVER);
        return Result.success(meetingRepository.save(meetingEntity));
    }

    @GetMapping("/meeting/mine")
    public Result findAllMine(@PageableDefault(sort = "starttime", direction = Sort.Direction.DESC) Pageable pageable,
                              @RequestAttribute("user") UserEntity user) {
        return Result.success(meetingRepository.findAllBySponsor(user.getId(), pageable));
    }

    @GetMapping("/meeting/joined")
    public Result findAllJoinedMeeting(@PageableDefault(sort = "starttime", direction = Sort.Direction.DESC) Pageable pageable,
                                       @RequestAttribute("user") UserEntity user) {
        List<MeetingmemberEntity> meetingmemberEntities = meetingMemberRepository.findAllByUid(user.getId());
        Page<MeetingEntity> all = meetingRepository.findAllByIdIsIn(meetingmemberEntities.stream()
                .map(meetingmemberEntity -> meetingmemberEntity.getMid()).collect(Collectors.toList()), pageable);
        List<MeetingEntity> content = all.getContent();
        for (MeetingEntity m : content) {
            m.setSponsorDetail(userService.findUserWithoutFeatureById(m.getSponsor()));
        }
        return Result.success(all);
    }

    @GetMapping("/meeting/room/{id}")
    public Result findByRoom(@PathVariable String id,
                             @PageableDefault(sort = "endtime", direction = Sort.Direction.DESC) Pageable pageable) {
        Page<MeetingEntity> all = meetingRepository.findAllByRoom(id, pageable);
        List<MeetingEntity> content = all.getContent();
        for (MeetingEntity m : content) {
            m.setSponsorDetail(userService.findUserWithoutFeatureById(m.getSponsor()));
        }
        return Result.success(all);
    }

    @GetMapping("/meeting")
    public Result findAll(@PageableDefault(sort = "starttime", direction = Sort.Direction.DESC) Pageable pageable,
                          @RequestAttribute("user") UserEntity user) {
        List<MeetingmemberEntity> meetingmemberEntities = meetingMemberRepository.findAllByUid(user.getId());
        Page<MeetingEntity> all = meetingRepository.findAllByIdIsInOrSponsor(meetingmemberEntities.stream()
                        .map(meetingmemberEntity -> meetingmemberEntity.getMid()).collect(Collectors.toList()),
                user.getId(), pageable);

        List<MeetingEntity> meetingEntities = all.getContent();
        for (MeetingEntity m : meetingEntities) {
            m.setSponsorDetail(userService.findUserWithoutFeatureById(m.getSponsor()));
        }

        return Result.success(all);
    }

    @GetMapping("/meeting/{id}")
    public Result findById(@PathVariable Integer id) {
        MeetingEntity meetingEntity = meetingRepository.findById(id).get();
        meetingEntity.setSponsorDetail(userService.findUserWithoutFeatureById(meetingEntity.getSponsor()));
        return Result.success(meetingEntity);
    }

    @DeleteMapping("/meeting/{id}")
    public Result cancel(@PathVariable Integer id,
                         @RequestAttribute("user") UserEntity user) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepository.findBySponsorAndId(user.getId(), id);
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity meetingEntity = optionalMeetingEntity.get();
            meetingEntity.setState(MeetingState.CANCELED);
            return Result.success(meetingRepository.save(meetingEntity));
        } else {
            return Result.error("未找到您发起的此会议");
        }
    }

    @PutMapping("/meeting")
    public Result userUpdateMeeting(@RequestBody @Valid UserUpdateMeetingDto userUpdateMeetingDto,
                                    @RequestAttribute("user") UserEntity user) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepository.findById(userUpdateMeetingDto.getId());
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity meetingEntity = optionalMeetingEntity.get();
            if (user.getId().equals(meetingEntity.getSponsor())) {
                BeanUtils.copyProperties(userUpdateMeetingDto, meetingEntity);
                return Result.success(meetingRepository.save(meetingEntity));
            } else {
                return Result.error("您不是会议发起人");
            }
        }
        return Result.error("无此会议");
    }

    @PostMapping("/meeting/{id}/invitationCode")
    public Result generateInvitationCode(@PathVariable Integer id) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepository.findById(id);
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity meetingEntity = optionalMeetingEntity.get();
            meetingEntity.setInvitationcode(UUID.randomUUID().toString().replaceAll("-", ""));
            return Result.success(meetingRepository.save(meetingEntity));
        } else {
            return Result.error("无此会议");
        }
    }

    @GetMapping("/meeting/invitationCode/{code}")
    public Result findByInvitationCode(@PathVariable String code) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepository.findByInvitationcode(code);
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity meetingEntity = optionalMeetingEntity.get();
            meetingEntity.setSponsorDetail(userService.findUserWithoutFeatureById(meetingEntity.getSponsor()));
            return Result.success(meetingEntity);
        } else {
            return Result.error("无此会议");
        }
    }

    @PutMapping("/a/meeting")
    public Result adminUpdateMeeting(@RequestBody @Valid AdminUpdateMeetingDto adminUpdateMeetingDto) {
        Optional<MeetingEntity> optionalMeetingEntity = meetingRepository.findById(adminUpdateMeetingDto.getId());
        if (optionalMeetingEntity.isPresent()) {
            MeetingEntity meetingEntity = optionalMeetingEntity.get();
            BeanUtils.copyProperties(adminUpdateMeetingDto, meetingEntity);
            if (adminUpdateMeetingDto.getState() == MeetingState.CHECK_SUCCESS) {
                meetingEntity.setInvitationcode(UUID.randomUUID().toString().replaceAll("-", ""));
            }
            messageService.newMessage(MessageType.MeetingCheck, meetingEntity, meetingEntity.getSponsor());
            return Result.success(meetingRepository.save(meetingEntity));
        }
        return Result.error("无此会议");
    }

    @GetMapping("/a/meeting")
    public Result adminFindAllMeeting(@RequestParam(defaultValue = "1") Integer state,
                                      Pageable pageable) {
        Page<MeetingEntity> result;
        if (state > 0) {
            result = meetingRepository.findAllByIdNotNullOrderByStarttimeDesc(pageable);
        } else {
            result = meetingRepository.findAllByStateOrderByStarttimeDesc(state, pageable);
        }
        List<MeetingEntity> content = result.getContent();
        for (MeetingEntity m : content) {
            m.setSponsorDetail(userService.findUserWithoutFeatureById(m.getSponsor()));
        }
        return Result.success(result);
    }


    @GetMapping("/meeting/auto")
    public Result auto()
    {
        meetingService.autoMeeting();
        return Result.success("成功");
    }


    @PostMapping("/meeting/urgent")
    public Result cutLine(@RequestBody MeetingDto meetingDto, @RequestAttribute("user")UserEntity user){
       List<MeetingEntity> meetingEntities= meetingRepository.findByStarttimeBetweenAndEndtimeBetweenAndRoom(meetingDto.getStarttime()-900,meetingDto.getEndtime()+900,
                meetingDto.getStarttime()+900,meetingDto.getEndtime()-900,meetingDto.getRoom());
       if (meetingEntities.size()>0){
           for (int i=0;i<meetingEntities.size();i++){
               MeetingEntity meetingEntity=meetingEntities.get(i);
               UserEntity pasp=userRepository.findById(meetingEntity.getSponsor()).get();
               if (user.getPermission()-pasp.getPermission()>=30){
                   MeetingEntity nmeeting=new MeetingEntity();
                   BeanUtils.copyProperties(meetingDto, nmeeting);
                   nmeeting.setSponsor(user.getId());
                   nmeeting.setState(MeetingState.CHECK_PENDING);
                   nmeeting.setAdjust(MeetingAdjust.NEVER);
                   meetingRepository.save(nmeeting);
                   meetingEntity.setState(MeetingState.CANCELED);
                   meetingRepository.save(meetingEntity);
                   return Result.success(nmeeting);
               }
                   }
                   return Result.error("权限不足");
                   }

          else{
              return save(meetingDto,user);
       }

       }
    }



